package com.cxl.live.websocket.util;

import com.alibaba.fastjson.JSON;
import com.cxl.live.websocket.model.Message;
import com.cxl.live.websocket.model.ResultMessage;
import com.cxl.live.websocket.service.RoomService;
import lombok.extern.slf4j.Slf4j;

import javax.websocket.Session;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;

/**
 * @Description: RoomWebSocketUtil
 * @Author: ChenXueLi
 * @Date: 2019-01-30 14:24
 * 你是一段成熟的代码，要学会自己改bug
 */
@Slf4j
public class WebSocketUtil {

    /**
     * 单例模式
     */
    private static volatile WebSocketUtil INSTANCE;
    private WebSocketUtil() {}

    public static WebSocketUtil getInstance() {
        synchronized (WebSocketUtil.class){
            if (INSTANCE == null) {
                INSTANCE = new WebSocketUtil();
            }
            return INSTANCE;
        }
    }

    /**
     * 处理数据（利用前端的信息，用反射的方法查找方法并返回信息）
     * @param session 会话
     * @param message 消息对象
     */
    public void handleAction(Session session, Message message) {
        // 创建返回信息对象
        ResultMessage resultMessage = new ResultMessage(message);

        Class<?> clazz = RoomService.class;
        Method method = null;
        try {
            method = clazz.getMethod(message.getAction(), Message.class);
        } catch (NoSuchMethodException e) {
            // 方法未找到
            sendErrorMessage(session, "方法未找到", resultMessage);
            e.printStackTrace();
        }

        if(method != null) {
            try {
                method.invoke(clazz.newInstance(), message);
            } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
                // 方法内部错误
                sendErrorMessage(session, "方法内部错误", resultMessage);
                e.printStackTrace();
            }
        }
    }

    /**
     * 发送错误信息
     * @param session
     * @param errorMessage
     * @param resultMessage
     */
    private void sendErrorMessage(Session session, String errorMessage, ResultMessage resultMessage) {
        // 日志输出错误信息
        log.error(errorMessage);
        // 设置发送消息失败
        resultMessage.setFlag(false);
        // 发送数据给客户端
        sendMessage(session, JSON.toJSONString(resultMessage));
    }

    /**
     * 推送消息
     * @param session
     * @param message
     * @throws IOException
     */
    public void sendMessage(Session session, String message){
        try {
            session.getBasicRemote().sendText(message);
        } catch (IOException e) {
            log.info(session.getId() + " 消息发送错误");
        }
    }

    /**
     * 群发自定义消息
     * @param sessionList
     * @param message
     */
    public void sendMessage(List<Session> sessionList, String message) {
        for (Session session : sessionList) {
           sendMessage(session, message);
        }
    }

    /**
     * 群发自定义消息
     * @param sessionHashSet
     * @param message
     */
    public void sendMessage(HashSet<Session> sessionHashSet, String message) {
        for (Session session : sessionHashSet) {
            sendMessage(session, message);
        }
    }

}
